home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / MorphOS / cvs-1.11.2 / source / amiga / ssh / md5.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-18  |  6.4 KB  |  219 lines

  1. /*
  2.  * MD5 implementation for PuTTY. Written directly from the spec by
  3.  * Simon Tatham.
  4.  */
  5.  
  6. #include <string.h>
  7.  
  8. #include "ssh.h"
  9. #include "md5.h"
  10.  
  11. /* ----------------------------------------------------------------------
  12.  * Core MD5 algorithm: processes 16-word blocks into a message digest.
  13.  */
  14.  
  15. #define F(x,y,z) ( ((x) & (y)) | ((~(x)) & (z)) )
  16. #define G(x,y,z) ( ((x) & (z)) | ((~(z)) & (y)) )
  17. #define H(x,y,z) ( (x) ^ (y) ^ (z) )
  18. #define I(x,y,z) ( (y) ^ ( (x) | ~(z) ) )
  19.  
  20. #define rol(x,y) ( ((x) << (y)) | (((unsigned long)x) >> (32-y)) )
  21.  
  22. #define subround(f,w,x,y,z,k,s,ti) \
  23.        w = x + rol(w + f(x,y,z) + block[k] + ti, s)
  24.  
  25. static void 
  26. MD5_Core_Init (MD5_Core_State * s)
  27. {
  28.   s->h[0] = 0x67452301;
  29.   s->h[1] = 0xefcdab89;
  30.   s->h[2] = 0x98badcfe;
  31.   s->h[3] = 0x10325476;
  32. }
  33.  
  34. static void 
  35. MD5_Block (MD5_Core_State * s, unsigned long *block)
  36. {
  37.   unsigned long a, b, c, d;
  38.  
  39.   a = s->h[0];
  40.   b = s->h[1];
  41.   c = s->h[2];
  42.   d = s->h[3];
  43.  
  44.   subround (F, a, b, c, d, 0, 7, 0xd76aa478);
  45.   subround (F, d, a, b, c, 1, 12, 0xe8c7b756);
  46.   subround (F, c, d, a, b, 2, 17, 0x242070db);
  47.   subround (F, b, c, d, a, 3, 22, 0xc1bdceee);
  48.   subround (F, a, b, c, d, 4, 7, 0xf57c0faf);
  49.   subround (F, d, a, b, c, 5, 12, 0x4787c62a);
  50.   subround (F, c, d, a, b, 6, 17, 0xa8304613);
  51.   subround (F, b, c, d, a, 7, 22, 0xfd469501);
  52.   subround (F, a, b, c, d, 8, 7, 0x698098d8);
  53.   subround (F, d, a, b, c, 9, 12, 0x8b44f7af);
  54.   subround (F, c, d, a, b, 10, 17, 0xffff5bb1);
  55.   subround (F, b, c, d, a, 11, 22, 0x895cd7be);
  56.   subround (F, a, b, c, d, 12, 7, 0x6b901122);
  57.   subround (F, d, a, b, c, 13, 12, 0xfd987193);
  58.   subround (F, c, d, a, b, 14, 17, 0xa679438e);
  59.   subround (F, b, c, d, a, 15, 22, 0x49b40821);
  60.   subround (G, a, b, c, d, 1, 5, 0xf61e2562);
  61.   subround (G, d, a, b, c, 6, 9, 0xc040b340);
  62.   subround (G, c, d, a, b, 11, 14, 0x265e5a51);
  63.   subround (G, b, c, d, a, 0, 20, 0xe9b6c7aa);
  64.   subround (G, a, b, c, d, 5, 5, 0xd62f105d);
  65.   subround (G, d, a, b, c, 10, 9, 0x02441453);
  66.   subround (G, c, d, a, b, 15, 14, 0xd8a1e681);
  67.   subround (G, b, c, d, a, 4, 20, 0xe7d3fbc8);
  68.   subround (G, a, b, c, d, 9, 5, 0x21e1cde6);
  69.   subround (G, d, a, b, c, 14, 9, 0xc33707d6);
  70.   subround (G, c, d, a, b, 3, 14, 0xf4d50d87);
  71.   subround (G, b, c, d, a, 8, 20, 0x455a14ed);
  72.   subround (G, a, b, c, d, 13, 5, 0xa9e3e905);
  73.   subround (G, d, a, b, c, 2, 9, 0xfcefa3f8);
  74.   subround (G, c, d, a, b, 7, 14, 0x676f02d9);
  75.   subround (G, b, c, d, a, 12, 20, 0x8d2a4c8a);
  76.   subround (H, a, b, c, d, 5, 4, 0xfffa3942);
  77.   subround (H, d, a, b, c, 8, 11, 0x8771f681);
  78.   subround (H, c, d, a, b, 11, 16, 0x6d9d6122);
  79.   subround (H, b, c, d, a, 14, 23, 0xfde5380c);
  80.   subround (H, a, b, c, d, 1, 4, 0xa4beea44);
  81.   subround (H, d, a, b, c, 4, 11, 0x4bdecfa9);
  82.   subround (H, c, d, a, b, 7, 16, 0xf6bb4b60);
  83.   subround (H, b, c, d, a, 10, 23, 0xbebfbc70);
  84.   subround (H, a, b, c, d, 13, 4, 0x289b7ec6);
  85.   subround (H, d, a, b, c, 0, 11, 0xeaa127fa);
  86.   subround (H, c, d, a, b, 3, 16, 0xd4ef3085);
  87.   subround (H, b, c, d, a, 6, 23, 0x04881d05);
  88.   subround (H, a, b, c, d, 9, 4, 0xd9d4d039);
  89.   subround (H, d, a, b, c, 12, 11, 0xe6db99e5);
  90.   subround (H, c, d, a, b, 15, 16, 0x1fa27cf8);
  91.   subround (H, b, c, d, a, 2, 23, 0xc4ac5665);
  92.   subround (I, a, b, c, d, 0, 6, 0xf4292244);
  93.   subround (I, d, a, b, c, 7, 10, 0x432aff97);
  94.   subround (I, c, d, a, b, 14, 15, 0xab9423a7);
  95.   subround (I, b, c, d, a, 5, 21, 0xfc93a039);
  96.   subround (I, a, b, c, d, 12, 6, 0x655b59c3);
  97.   subround (I, d, a, b, c, 3, 10, 0x8f0ccc92);
  98.   subround (I, c, d, a, b, 10, 15, 0xffeff47d);
  99.   subround (I, b, c, d, a, 1, 21, 0x85845dd1);
  100.   subround (I, a, b, c, d, 8, 6, 0x6fa87e4f);
  101.   subround (I, d, a, b, c, 15, 10, 0xfe2ce6e0);
  102.   subround (I, c, d, a, b, 6, 15, 0xa3014314);
  103.   subround (I, b, c, d, a, 13, 21, 0x4e0811a1);
  104.   subround (I, a, b, c, d, 4, 6, 0xf7537e82);
  105.   subround (I, d, a, b, c, 11, 10, 0xbd3af235);
  106.   subround (I, c, d, a, b, 2, 15, 0x2ad7d2bb);
  107.   subround (I, b, c, d, a, 9, 21, 0xeb86d391);
  108.  
  109.   s->h[0] += a;
  110.   s->h[1] += b;
  111.   s->h[2] += c;
  112.   s->h[3] += d;
  113. }
  114.  
  115. /* ----------------------------------------------------------------------
  116.  * Outer MD5 algorithm: take an arbitrary length byte string,
  117.  * convert it into 16-word blocks with the prescribed padding at
  118.  * the end, and pass those blocks to the core MD5 algorithm.
  119.  */
  120.  
  121. #define BLKSIZE 64
  122.  
  123. void 
  124. MD5Init (struct MD5Context *s)
  125. {
  126.   MD5_Core_Init (&s->core);
  127.   s->blkused = 0;
  128.   s->lenhi = s->lenlo = 0;
  129. }
  130.  
  131. void 
  132. MD5Update (struct MD5Context *s, unsigned char const *p, unsigned len)
  133. {
  134.   unsigned char *q = (unsigned char *) p;
  135.   unsigned long wordblock[16];
  136.   unsigned long lenw = len;
  137.   int i;
  138.  
  139.   /*
  140.    * Update the length field.
  141.    */
  142.   s->lenlo += lenw;
  143.   s->lenhi += (s->lenlo < lenw);
  144.  
  145.   if (s->blkused + len < BLKSIZE)
  146.   {
  147.     /*
  148.      * Trivial case: just add to the block.
  149.      */
  150.     memcpy (s->block + s->blkused, q, len);
  151.     s->blkused += len;
  152.   }
  153.   else
  154.   {
  155.     /*
  156.      * We must complete and process at least one block.
  157.      */
  158.     while (s->blkused + len >= BLKSIZE)
  159.     {
  160.       memcpy (s->block + s->blkused, q, BLKSIZE - s->blkused);
  161.       q += BLKSIZE - s->blkused;
  162.       len -= BLKSIZE - s->blkused;
  163.       /* Now process the block. Gather bytes little-endian into words */
  164.       for (i = 0; i < 16; i++)
  165.       {
  166.         wordblock[i] =
  167.           (((unsigned long) s->block[i * 4 + 3]) << 24) |
  168.           (((unsigned long) s->block[i * 4 + 2]) << 16) |
  169.           (((unsigned long) s->block[i * 4 + 1]) << 8) |
  170.           (((unsigned long) s->block[i * 4 + 0]) << 0);
  171.       }
  172.       MD5_Block (&s->core, wordblock);
  173.       s->blkused = 0;
  174.     }
  175.     memcpy (s->block, q, len);
  176.     s->blkused = len;
  177.   }
  178. }
  179.  
  180. void 
  181. MD5Final (unsigned char output[16], struct MD5Context *s)
  182. {
  183.   int i;
  184.   unsigned pad;
  185.   unsigned char c[64];
  186.   unsigned long lenhi, lenlo;
  187.  
  188.   if (s->blkused >= 56)
  189.     pad = 56 + 64 - s->blkused;
  190.   else
  191.     pad = 56 - s->blkused;
  192.  
  193.   lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));
  194.   lenlo = (s->lenlo << 3);
  195.  
  196.   memset (c, 0, pad);
  197.   c[0] = 0x80;
  198.   MD5Update (s, c, pad);
  199.  
  200.   c[7] = (lenhi >> 24) & 0xFF;
  201.   c[6] = (lenhi >> 16) & 0xFF;
  202.   c[5] = (lenhi >> 8) & 0xFF;
  203.   c[4] = (lenhi >> 0) & 0xFF;
  204.   c[3] = (lenlo >> 24) & 0xFF;
  205.   c[2] = (lenlo >> 16) & 0xFF;
  206.   c[1] = (lenlo >> 8) & 0xFF;
  207.   c[0] = (lenlo >> 0) & 0xFF;
  208.  
  209.   MD5Update (s, c, 8);
  210.  
  211.   for (i = 0; i < 4; i++)
  212.   {
  213.     output[4 * i + 3] = (s->core.h[i] >> 24) & 0xFF;
  214.     output[4 * i + 2] = (s->core.h[i] >> 16) & 0xFF;
  215.     output[4 * i + 1] = (s->core.h[i] >> 8) & 0xFF;
  216.     output[4 * i + 0] = (s->core.h[i] >> 0) & 0xFF;
  217.   }
  218. }
  219.